{% extends 'base.html' %}

{% block title %}资产管理 - 固定资产管理系统{% endblock %}

{% block extra_css %}
<style>
/* 表头样式优化 */
.table-dark th {
    position: sticky;
    top: 0;
    z-index: 10;
    font-weight: 600;
    vertical-align: middle;
    padding: 12px 8px;
}

.table-dark .form-check-input {
    background-color: rgba(255,255,255,0.2) !important;
    border-color: rgba(255,255,255,0.3) !important;
}

.table-dark .form-check-input:checked {
    background-color: #fff !important;
    border-color: #fff !important;
}

.user-info {
    max-width: 120px;
    overflow: hidden;
}

.user-info strong {
    display: block;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* asset-table-container 样式统一到全局 CSS */

#assetListRoot .table-responsive {
    border-radius: 8px;
    /* 仅在需要时启用横向滚动，避免阻断纵向滚动 */
    overflow-x: auto;
    overflow-y: visible;
}

/* 优化操作列下拉框宽度 */
.action-dropdown {
    min-width: 120px !important;
    max-width: 150px !important;
}

.action-dropdown .dropdown-menu {
    min-width: 120px !important;
    max-width: 150px !important;
}

/* 按钮尺寸与下拉按钮具体样式在全局 CSS 定义，这里不重复 */

/* 操作按钮组优化 */
#assetListRoot .btn-group-sm .btn {
    padding: 0.25rem 0.4rem;
    font-size: 0.75rem;
}

#assetListRoot .btn-group-sm .dropdown-toggle::after {
    margin-left: 0.2rem;
}

/* 跳页输入优化：更窄并去除数字控件箭头 */
#assetListRoot #pageJumpInput {
    max-width: 56px; /* 略放大便于点选 */
    text-align: center;
    appearance: textfield; /* 标准属性，统一表现 */
    -moz-appearance: textfield; /* Firefox 去除箭头 */
}
#assetListRoot #pageJumpInput::-webkit-outer-spin-button,
#assetListRoot #pageJumpInput::-webkit-inner-spin-button {
    -webkit-appearance: none;
    margin: 0;
}

/* .btn-icon 在全局 CSS 统一定义 */

/* 跳页输入组美化 */
#assetListRoot .page-jump .input-group-text {
    background-color: #f8f9fa;
}
/* page-jump 使用默认按钮尺寸 */

/* 分页响应式优化 */
#assetListRoot .pagination { flex-wrap: wrap; }
#assetListRoot .pagination .page-link { min-width: 34px; text-align: center; }

/* 分页链接添加 per-page 选择器 */
#assetListRoot .pagination .page-link[per-page] {
    margin-left: 10px;
}

/* 轻微淡出过渡，用于分页切换的感知反馈 */
body.nav-fade {
    opacity: 0.85;
    transition: opacity .18s ease-in;
}

/* 回收功能样式 */
.recycle-item {
    color: #28a745;
}

.recycle-item:hover {
    color: #1e7e34;
    background-color: #f8f9fa;
}

/* 统一列表字体与徽章风格（增强层级：表头 > 正文） */
.table td { font-size: 0.8125rem; /* 13px 正文 */ vertical-align: middle; }
.table th { font-size: 0.875rem;   /* 14px 普通表头 */ vertical-align: middle; }
.table thead th { font-size: 0.9375rem; /* 15px 主要表头 */ }

/* 徽章字号略小于正文，保持和谐 */
.table .badge {
    font-size: 0.8125rem; /* 13px */
    padding: 0.30rem 0.45rem;
}

.asset-badge-org {
    background-color: #6c757d; /* bg-secondary */
    color: #fff;
    font-size: 0.8125rem; /* 13px，与徽章一致 */
    padding: 0.30rem 0.45rem;
    border-radius: 0.35rem;
}

.asset-badge-number {
    background-color: #0d6efd; /* primary */
    color: #fff; /* white text */
    font-size: 0.8125rem; /* 13px */
    padding: 0.28rem 0.5rem;
    border: 1px solid #0b5ed7; /* darker primary */
    border-radius: 999px; /* pill */
    font-weight: 600;
    letter-spacing: 0.3px;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    text-decoration: none;
    cursor: pointer;
    font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
}

.asset-badge-number .hash {
    opacity: .85;
}

.asset-badge-number:hover {
    background-color: #0b5ed7;
    border-color: #0a58ca;
    color: #fff;
    text-decoration: none;
    box-shadow: 0 2px 4px rgba(13,110,253,.2);
    transform: translateY(-1px);
}

.asset-name {
    font-weight: 600;
    font-size: 0.8125rem; /* 与表格正文保持一致（13px） */
}

/* 行密度切换：仅调整内边距，不改变字体大小，以保持视觉一致 */
.asset-density-comfortable .table td,
.asset-density-comfortable .table th { padding: 0.72rem 0.6rem; }
.asset-density-compact .table td,
.asset-density-compact .table th { padding: 0.40rem 0.45rem; }

.density-toggle .btn { padding: 0.2rem 0.5rem; font-size: 0.8125rem; }
.density-toggle .btn.active { background: #0d6efd; color: #fff; }

/* 选择工具条 */
.selection-toolbar {
    position: sticky;
    top: 0;
    z-index: 1020;
    background: #f0f7ff;
    border: 1px solid #cfe2ff;
    border-left: 4px solid #0d6efd;
    color: #0a58ca;
    padding: 8px 12px;
    border-radius: 6px;
    display: none;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    margin-bottom: 8px;
}
.selection-toolbar .btn { padding: 0.25rem 0.5rem; font-size: 0.8125rem; }

/* 过滤器与分页字号统一 */
.card .form-control,
.card .form-select { font-size: 0.9rem; }
.dropdown-menu .dropdown-item { font-size: 0.875rem; }
.pagination .page-link { font-size: 0.875rem; }

/* 与首页风格一致的字体与卡片样式 */
#assetListRoot {
    font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
    color: #2d3748;
}
#assetListRoot.card, #assetListRoot .card {
    border: 1px solid #e6e8ee;
    border-radius: 12px;
    box-shadow: none;
}
#assetListRoot .card-header h5 {
    font-size: 1.1rem; /* 与首页模块标题一致 */
    font-weight: 600;
    color: #1f2937;
}

/* 控件圆角与首页一致 */
#assetListRoot .btn,
#assetListRoot .form-control,
#assetListRoot .form-select,
#assetListRoot .dropdown-menu,
#assetListRoot .page-link {
    border-radius: 8px;
}

/* 状态小圆点（与首页色板一致风格） */
#assetListRoot .status-dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; margin-right: 6px; vertical-align: middle; }
#assetListRoot .dot-success { background: #38a169; }
#assetListRoot .dot-primary { background: #0d6efd; }
#assetListRoot .dot-info { background: #0ea5e9; }
#assetListRoot .dot-warning { background: #f59e0b; }
#assetListRoot .dot-danger { background: #e53e3e; }
#assetListRoot .dot-secondary { background: #6b7280; }
</style>
{% endblock %}

{% block content %}
<div class="row">
    <div class="col-md-12">
        <nav aria-label="breadcrumb">
            <ol class="breadcrumb">
                <li class="breadcrumb-item"><a href="{% url 'assets:index' %}">首页</a></li>
                <li class="breadcrumb-item active" aria-current="page">资产管理</li>
            </ol>
        </nav>
        
        <div class="d-flex justify-content-between align-items-center mb-3">
            <h2 class="mb-0 d-flex align-items-center gap-2">
                <i class="fas fa-boxes me-2"></i>
                <span>资产管理</span>
                {% if request.GET.organization %}
                <span class="badge bg-secondary" title="当前筛选的组织">
                    <i class="fas fa-building me-1"></i>
                    {% for org in organizations %}
                        {% if request.GET.organization == org.id|stringformat:"s" %}{{ org.name }}{% endif %}
                    {% endfor %}
                </span>
                {% endif %}
            </h2>
            <div class="d-flex align-items-center gap-2">
                <div class="btn-group density-toggle" role="group" aria-label="密度切换">
                    <button type="button" id="btnDensityComfort" class="btn btn-outline-secondary active" title="舒适">
                        舒适
                    </button>
                    <button type="button" id="btnDensityCompact" class="btn btn-outline-secondary" title="紧凑">
                        紧凑
                    </button>
                </div>
                <div class="btn-group">
                <a href="{% url 'assets:asset_create' %}" class="btn btn-primary" id="btnOpenCreateAsset">
                    <i class="fas fa-plus me-1"></i>新增资产
                </a>
                <button type="button" class="btn btn-outline-primary dropdown-toggle dropdown-toggle-split" data-bs-toggle="dropdown">
                    <span class="visually-hidden">更多操作</span>
                </button>
                <ul class="dropdown-menu">
                    <li><a class="dropdown-item" href="{% url 'assets:bulk_import_assets' %}">
                        <i class="fas fa-upload me-2"></i>批量导入
                    </a></li>
                    <li><hr class="dropdown-divider"></li>
                    <li><a class="dropdown-item text-warning" href="#" onclick="batchUpdateStatus()">
                        <i class="fas fa-edit me-2"></i>批量更新状态
                    </a></li>
                    <li><a class="dropdown-item text-danger" href="#" id="btnMenuBatchDelete">
                        <i class="fas fa-trash me-2"></i>批量删除
                    </a></li>
                </ul>
                </div>
            </div>
        </div>
        
        <!-- 搜索和筛选 -->
        <div class="card mb-4">
            <div class="card-body">
                <form method="get" class="d-flex flex-wrap align-items-center gap-2">
                    <div style="width: 280px; min-width: 250px;">
                        <div class="input-group">
                            <input type="text" class="form-control" name="search" placeholder="搜索资产名称或编号..." value="{{ search_query }}">
                            <button class="btn btn-outline-secondary" type="submit">
                                <i class="fas fa-search me-1"></i>搜索
                            </button>
                        </div>
                    </div>
                    <div style="min-width: 120px;">
                        <select class="form-select form-select-sm" name="category" onchange="this.form.submit()">
                            <option value="">全部类别</option>
                            {% for category in categories %}
                                <option value="{{ category.id }}" {% if request.GET.category == category.id|stringformat:"s" %}selected{% endif %}>
                                    {{ category.name }}
                                </option>
                            {% endfor %}
                        </select>
                    </div>
                    <div style="min-width: 140px;">
                        <select class="form-select form-select-sm" name="organization" onchange="this.form.submit()">
                            <option value="">全部组织</option>
                            {% for org in organizations %}
                                <option value="{{ org.id }}" {% if request.GET.organization == org.id|stringformat:"s" %}selected{% endif %}>{{ org.name }}</option>
                            {% endfor %}
                        </select>
                    </div>
                    <!-- 已移除账簿筛选：仅按组织筛选即可 -->
                    <div style="min-width: 100px;">
                        <select class="form-select form-select-sm" name="status" onchange="this.form.submit()">
                            <option value="">全部状态</option>
                            <option value="idle" {% if request.GET.status == 'idle' %}selected{% endif %}>闲置</option>
                            <option value="in_use" {% if request.GET.status == 'in_use' %}selected{% endif %}>在用</option>
                            <option value="borrowed" {% if request.GET.status == 'borrowed' %}selected{% endif %}>已借出</option>
                            <option value="maintenance" {% if request.GET.status == 'maintenance' %}selected{% endif %}>维修中</option>
                            <option value="faulty" {% if request.GET.status == 'faulty' %}selected{% endif %}>故障</option>
                            <option value="scrapped" {% if request.GET.status == 'scrapped' %}selected{% endif %}>已报废</option>
                        </select>
                    </div>
                    <div style="min-width: 120px;">
                        <select class="form-select form-select-sm" name="department" onchange="this.form.submit()">
                            <option value="">全部部门</option>
                            {% for department in departments %}
                                <option value="{{ department.id }}" {% if request.GET.department == department.id|stringformat:"s" %}selected{% endif %}>
                                    {{ department.name }}
                                </option>
                            {% endfor %}
                        </select>
                    </div>
                    <div style="min-width: 120px;">
                        <select class="form-select form-select-sm" name="user" onchange="this.form.submit()">
                            <option value="">全部使用人</option>
                            <option value="unassigned" {% if request.GET.user == 'unassigned' %}selected{% endif %}>未分配</option>
                            {% for user in users %}
                                <option value="{{ user.id }}" {% if request.GET.user == user.id|stringformat:"s" %}selected{% endif %}>
                                    {{ user.get_full_name|default:user.username }}
                                </option>
                            {% endfor %}
                        </select>
                    </div>
                    <div>
                        <button type="button" class="btn btn-outline-info btn-sm" onclick="clearSearch()">
                            <i class="fas fa-times me-1"></i>清除
                        </button>
                    </div>
                </form>
            </div>
        </div>

        <!-- 资产列表 -->
        <div class="card asset-list-root asset-density-comfortable" id="assetListRoot" data-per-page="{{ per_page }}">
            <div class="card-header" id="assetListHeader">
                {% include 'assets/partials/asset_list_header.html' %}
            </div>
            <div class="card-body">
                <!-- 选择工具条 -->
                <div id="selectionToolbar" class="selection-toolbar">
                    <div>
                        <i class="fas fa-check-square me-1"></i>
                        已选择 <strong id="selectedCount">0</strong> 项
                    </div>
                    <div class="d-flex align-items-center gap-2">
                        <button type="button" class="btn btn-outline-primary btn-sm" onclick="batchUpdateStatus()">
                            <i class="fas fa-edit me-1"></i>更新状态
                        </button>
                        <button type="button" class="btn btn-outline-success btn-sm" id="btnBatchRecycle">
                            <i class="fas fa-recycle me-1"></i>回收
                        </button>
                        <button type="button" class="btn btn-outline-danger btn-sm" id="btnBatchDelete">
                            <i class="fas fa-trash me-1"></i>删除
                        </button>
                        <button type="button" class="btn btn-outline-secondary btn-sm" id="btnClearSelection">
                            清除选择
                        </button>
                    </div>
                </div>
                <form id="batchActionForm" method="post">
                    {% csrf_token %}
                    <div class="table-responsive asset-table-container">
                        <table class="table table-striped table-hover mb-0">
                            <thead class="table-dark">
                                <tr>
                                    <th width="4%">
                                        <input type="checkbox" class="form-check-input" id="selectAllHeader" onchange="toggleSelectAll()" title="点击全选/取消全选">
                                    </th>
                                    <th width="12%">
                                        {% with field='organization' %}
                                        <a class="text-white text-decoration-none" href="{% url 'assets:asset_list' %}?page=1{% if search_query %}&search={{ search_query }}{% endif %}{% if request.GET.category %}&category={{ request.GET.category }}{% endif %}{% if request.GET.organization %}&organization={{ request.GET.organization }}{% endif %}{% if request.GET.status %}&status={{ request.GET.status }}{% endif %}{% if request.GET.department %}&department={{ request.GET.department }}{% endif %}{% if request.GET.user %}&user={{ request.GET.user }}{% endif %}&sort={{ field }}&order={% if sort == field and order == 'asc' %}desc{% else %}asc{% endif %}&per_page={{ per_page }}">
                                            所属组织
                                            {% if sort == field %}
                                                {% if order == 'asc' %}<i class="fas fa-sort-up ms-1"></i>{% else %}<i class="fas fa-sort-down ms-1"></i>{% endif %}
                                            {% endif %}
                                        </a>
                                        {% endwith %}
                                    </th>
                                    <th width="10%">
                                        {% with field='asset_number' %}
                                        <a class="text-white text-decoration-none" href="{% url 'assets:asset_list' %}?page=1{% if search_query %}&search={{ search_query }}{% endif %}{% if request.GET.category %}&category={{ request.GET.category }}{% endif %}{% if request.GET.organization %}&organization={{ request.GET.organization }}{% endif %}{% if request.GET.status %}&status={{ request.GET.status }}{% endif %}{% if request.GET.department %}&department={{ request.GET.department }}{% endif %}{% if request.GET.user %}&user={{ request.GET.user }}{% endif %}&sort={{ field }}&order={% if sort == field and order == 'asc' %}desc{% else %}asc{% endif %}&per_page={{ per_page }}">
                                            资产编号
                                            {% if sort == field %}
                                                {% if order == 'asc' %}<i class="fas fa-sort-up ms-1"></i>{% else %}<i class="fas fa-sort-down ms-1"></i>{% endif %}
                                            {% endif %}
                                        </a>
                                        {% endwith %}
                                    </th>
                                    <th width="16%">
                                        {% with field='name' %}
                                        <a class="text-white text-decoration-none" href="{% url 'assets:asset_list' %}?page=1{% if search_query %}&search={{ search_query }}{% endif %}{% if request.GET.category %}&category={{ request.GET.category }}{% endif %}{% if request.GET.organization %}&organization={{ request.GET.organization }}{% endif %}{% if request.GET.status %}&status={{ request.GET.status }}{% endif %}{% if request.GET.department %}&department={{ request.GET.department }}{% endif %}{% if request.GET.user %}&user={{ request.GET.user }}{% endif %}&sort={{ field }}&order={% if sort == field and order == 'asc' %}desc{% else %}asc{% endif %}&per_page={{ per_page }}">
                                            资产名称
                                            {% if sort == field %}
                                                {% if order == 'asc' %}<i class="fas fa-sort-up ms-1"></i>{% else %}<i class="fas fa-sort-down ms-1"></i>{% endif %}
                                            {% endif %}
                                        </a>
                                        {% endwith %}
                                    </th>
                                    <th width="9%">
                                        {% with field='category' %}
                                        <a class="text-white text-decoration-none" href="{% url 'assets:asset_list' %}?page=1{% if search_query %}&search={{ search_query }}{% endif %}{% if request.GET.category %}&category={{ request.GET.category }}{% endif %}{% if request.GET.organization %}&organization={{ request.GET.organization }}{% endif %}{% if request.GET.status %}&status={{ request.GET.status }}{% endif %}{% if request.GET.department %}&department={{ request.GET.department }}{% endif %}{% if request.GET.user %}&user={{ request.GET.user }}{% endif %}&sort={{ field }}&order={% if sort == field and order == 'asc' %}desc{% else %}asc{% endif %}&per_page={{ per_page }}">
                                            类别
                                            {% if sort == field %}
                                                {% if order == 'asc' %}<i class="fas fa-sort-up ms-1"></i>{% else %}<i class="fas fa-sort-down ms-1"></i>{% endif %}
                                            {% endif %}
                                        </a>
                                        {% endwith %}
                                    </th>
                                    <th width="9%">
                                        {% with field='status' %}
                                        <a class="text-white text-decoration-none" href="{% url 'assets:asset_list' %}?page=1{% if search_query %}&search={{ search_query }}{% endif %}{% if request.GET.category %}&category={{ request.GET.category }}{% endif %}{% if request.GET.organization %}&organization={{ request.GET.organization }}{% endif %}{% if request.GET.status %}&status={{ request.GET.status }}{% endif %}{% if request.GET.department %}&department={{ request.GET.department }}{% endif %}{% if request.GET.user %}&user={{ request.GET.user }}{% endif %}&sort={{ field }}&order={% if sort == field and order == 'asc' %}desc{% else %}asc{% endif %}&per_page={{ per_page }}">
                                            状态
                                            {% if sort == field %}
                                                {% if order == 'asc' %}<i class="fas fa-sort-up ms-1"></i>{% else %}<i class="fas fa-sort-down ms-1"></i>{% endif %}
                                            {% endif %}
                                        </a>
                                        {% endwith %}
                                    </th>
                                    <th width="10%">
                                        {% with field='department' %}
                                        <a class="text-white text-decoration-none" href="{% url 'assets:asset_list' %}?page=1{% if search_query %}&search={{ search_query }}{% endif %}{% if request.GET.category %}&category={{ request.GET.category }}{% endif %}{% if request.GET.organization %}&organization={{ request.GET.organization }}{% endif %}{% if request.GET.status %}&status={{ request.GET.status }}{% endif %}{% if request.GET.department %}&department={{ request.GET.department }}{% endif %}{% if request.GET.user %}&user={{ request.GET.user }}{% endif %}&sort={{ field }}&order={% if sort == field and order == 'asc' %}desc{% else %}asc{% endif %}&per_page={{ per_page }}">
                                            所属部门
                                            {% if sort == field %}
                                                {% if order == 'asc' %}<i class="fas fa-sort-up ms-1"></i>{% else %}<i class="fas fa-sort-down ms-1"></i>{% endif %}
                                            {% endif %}
                                        </a>
                                        {% endwith %}
                                    </th>
                                    <th width="10%">
                                        {% with field='user' %}
                                        <a class="text-white text-decoration-none" href="{% url 'assets:asset_list' %}?page=1{% if search_query %}&search={{ search_query }}{% endif %}{% if request.GET.category %}&category={{ request.GET.category }}{% endif %}{% if request.GET.organization %}&organization={{ request.GET.organization }}{% endif %}{% if request.GET.status %}&status={{ request.GET.status }}{% endif %}{% if request.GET.department %}&department={{ request.GET.department }}{% endif %}{% if request.GET.user %}&user={{ request.GET.user }}{% endif %}&sort={{ field }}&order={% if sort == field and order == 'asc' %}desc{% else %}asc{% endif %}&per_page={{ per_page }}">
                                            使用人
                                            {% if sort == field %}
                                                {% if order == 'asc' %}<i class="fas fa-sort-up ms-1"></i>{% else %}<i class="fas fa-sort-down ms-1"></i>{% endif %}
                                            {% endif %}
                                        </a>
                                        {% endwith %}
                                    </th>
                                    <th width="9%">
                                        {% with field='purchase_price' %}
                                        <a class="text-white text-decoration-none" href="{% url 'assets:asset_list' %}?page=1{% if search_query %}&search={{ search_query }}{% endif %}{% if request.GET.category %}&category={{ request.GET.category }}{% endif %}{% if request.GET.organization %}&organization={{ request.GET.organization }}{% endif %}{% if request.GET.status %}&status={{ request.GET.status }}{% endif %}{% if request.GET.department %}&department={{ request.GET.department }}{% endif %}{% if request.GET.user %}&user={{ request.GET.user }}{% endif %}&sort={{ field }}&order={% if sort == field and order == 'asc' %}desc{% else %}asc{% endif %}&per_page={{ per_page }}">
                                            采购价格
                                            {% if sort == field %}
                                                {% if order == 'asc' %}<i class="fas fa-sort-up ms-1"></i>{% else %}<i class="fas fa-sort-down ms-1"></i>{% endif %}
                                            {% endif %}
                                        </a>
                                        {% endwith %}
                                    </th>
                                    <th width="11%">
                                        {% with field='purchase_date' %}
                                        <a class="text-white text-decoration-none" href="{% url 'assets:asset_list' %}?page=1{% if search_query %}&search={{ search_query }}{% endif %}{% if request.GET.category %}&category={{ request.GET.category }}{% endif %}{% if request.GET.organization %}&organization={{ request.GET.organization }}{% endif %}{% if request.GET.status %}&status={{ request.GET.status }}{% endif %}{% if request.GET.department %}&department={{ request.GET.department }}{% endif %}{% if request.GET.user %}&user={{ request.GET.user }}{% endif %}&sort={{ field }}&order={% if sort == field and order == 'asc' %}desc{% else %}asc{% endif %}&per_page={{ per_page }}">
                                            启用日期
                                            {% if sort == field %}
                                                {% if order == 'asc' %}<i class="fas fa-sort-up ms-1"></i>{% else %}<i class="fas fa-sort-down ms-1"></i>{% endif %}
                                            {% endif %}
                                        </a>
                                        {% endwith %}
                                    </th>
                                    <th width="12%">操作</th>
                                </tr>
                            </thead>
                            <tbody>
                                {% include 'assets/partials/asset_table_body.html' %}
                            </tbody>
                        </table>
                    </div>
                </form>
            </div>
        </div>

        <!-- 分页 -->
        <div id="assetListPagination">
            {% include 'assets/partials/asset_pagination.html' %}
        </div>
    </div>
</div>

<!-- 通用操作模态框（Iframe） 已移除：统一改为 AJAX 模态 -->

<!-- 确认操作模态框（POST 提交） -->
<div class="modal fade" id="confirmActionModal" tabindex="-1" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title" id="confirmActionTitle">确认操作</h5>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="关闭"></button>
      </div>
      <div class="modal-body">
        <pre id="confirmActionMessage" class="mb-0" style="white-space:pre-wrap;"></pre>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
        <button type="button" class="btn btn-danger" id="confirmActionBtn" data-post-url="">确定</button>
      </div>
    </div>
  </div>
</div>

<!-- 全局成功 Toast 容器（居中置顶） -->
<div class="position-fixed top-0 start-50 translate-middle-x p-3" style="z-index: 1080;">
  <div id="globalToast" class="toast align-items-center text-bg-success border-0" role="alert" aria-live="assertive" aria-atomic="true">
    <div class="d-flex">
      <div class="toast-body" id="globalToastBody">操作成功</div>
      <button type="button" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast" aria-label="Close"></button>
    </div>
  </div>
</div>

<!-- 新增资产（AJAX）模态框 -->
<div class="modal fade" id="assetCreateModal" tabindex="-1" aria-hidden="true">
  <div class="modal-dialog modal-xl modal-dialog-scrollable">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title">新增资产</h5>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="关闭"></button>
      </div>
      <div class="modal-body" id="assetCreateModalBody">
        <div class="d-flex align-items-center justify-content-center py-5 text-muted">
          <div class="text-center">
            <div class="spinner-border text-primary" role="status" aria-label="加载中"></div>
            <div class="mt-2 small">正在加载表单…</div>
          </div>
        </div>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">关闭</button>
        <button type="button" class="btn btn-primary" id="assetCreateSubmitBtn">保存</button>
      </div>
    </div>
  </div>
  </div>

<!-- 通用资产操作（AJAX）模态框 -->
<div class="modal fade" id="assetActionAjaxModal" tabindex="-1" aria-hidden="true">
  <div class="modal-dialog modal-lg modal-dialog-scrollable">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title" id="assetActionAjaxTitle">操作</h5>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="关闭"></button>
      </div>
      <div class="modal-body" id="assetActionAjaxBody">
        <div class="d-flex align-items-center justify-content-center py-5 text-muted">
          <div class="text-center">
            <div class="spinner-border text-primary" role="status" aria-label="加载中"></div>
            <div class="mt-2 small">正在加载表单…</div>
          </div>
        </div>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">关闭</button>
        <button type="button" class="btn btn-primary" id="assetActionAjaxSubmitBtn">保存</button>
      </div>
    </div>
  </div>
</div>

<script>
// 安全兜底，防止在定义前调用造成静态检查报错
window.updateSelectionToolbar = window.updateSelectionToolbar || function(){};

// 统一 Toast 展示方法
function showToast(message, type) {
    try {
        const toastEl = document.getElementById('globalToast');
        const toastBody = document.getElementById('globalToastBody');
        if (!toastEl) return;
        toastEl.classList.remove('text-bg-success', 'text-bg-danger');
        toastEl.classList.add(type === 'error' ? 'text-bg-danger' : 'text-bg-success');
        if (toastBody && message) toastBody.textContent = message;
        new bootstrap.Toast(toastEl).show();
    } catch (e) { /* no-op */ }
}

// 复制文本到剪贴板并给按钮提供轻量反馈
function copyText(btn, text) {
    if (!text) return;
    const doFeedback = (ok) => {
        try {
            if (!btn) return;
            const icon = btn.querySelector('i');
            const prevTitle = btn.getAttribute('title') || '';
            if (ok) {
                btn.classList.remove('btn-outline-secondary');
                btn.classList.add('btn-outline-success');
                if (icon) { icon.classList.remove('fa-copy'); icon.classList.add('fa-check'); }
                btn.setAttribute('title', '已复制');
                setTimeout(() => {
                    btn.classList.remove('btn-outline-success');
                    btn.classList.add('btn-outline-secondary');
                    if (icon) { icon.classList.remove('fa-check'); icon.classList.add('fa-copy'); }
                    btn.setAttribute('title', prevTitle);
                }, 1200);
            }
        } catch (e) { /* 忽略反馈异常 */ }
    };
    if (navigator.clipboard && navigator.clipboard.writeText) {
        navigator.clipboard.writeText(text).then(() => doFeedback(true)).catch(() => doFeedback(false));
    } else {
        // 回退方案
        const ta = document.createElement('textarea');
        ta.value = text; document.body.appendChild(ta); ta.select();
        try { document.execCommand('copy'); doFeedback(true); } catch (e) { doFeedback(false); }
        document.body.removeChild(ta);
    }
}
function toggleSelectAll() {
    const selectAllCheckbox = document.getElementById('selectAllHeader');
    const assetCheckboxes = document.querySelectorAll('.asset-checkbox');
    const isChecked = selectAllCheckbox.checked;
    
    assetCheckboxes.forEach(checkbox => {
        checkbox.checked = isChecked;
    });
    updateSelectionToolbar();
}

function batchUpdateStatus() {
    const checkedBoxes = document.querySelectorAll('.asset-checkbox:checked');
    
    if (checkedBoxes.length === 0) {
        alert('请选择要更新状态的资产');
        return;
    }
    
    // 创建状态选择对话框
    const statusOptions = [
        { value: 'idle', text: '闲置' },
        { value: 'in_use', text: '在用' },
        { value: 'borrowed', text: '已借出' },
        { value: 'maintenance', text: '维修中' },
        { value: 'faulty', text: '故障' },
        { value: 'scrapped', text: '已报废' }
    ];
    
    let optionsHtml = '';
    statusOptions.forEach(function(option) {
        optionsHtml += '<option value="' + option.value + '">' + option.text + '</option>';
    });
    
    const modalHtml = '' +
        '<div class="modal fade" id="statusUpdateModal" tabindex="-1">' +
            '<div class="modal-dialog">' +
                '<div class="modal-content">' +
                    '<div class="modal-header">' +
                        '<h5 class="modal-title">批量更新资产状态</h5>' +
                        '<button type="button" class="btn-close" data-bs-dismiss="modal"></button>' +
                    '</div>' +
                    '<div class="modal-body">' +
                        '<p>已选择 <strong>' + checkedBoxes.length + '</strong> 个资产，请选择新的状态：</p>' +
                        '<select class="form-select" id="newStatusSelect">' +
                            '<option value="">请选择状态</option>' +
                            optionsHtml +
                        '</select>' +
                    '</div>' +
                    '<div class="modal-footer">' +
                        '<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>' +
                        '<button type="button" class="btn btn-primary" onclick="confirmStatusUpdate()">确认更新</button>' +
                    '</div>' +
                '</div>' +
            '</div>' +
        '</div>';
    
    // 移除已存在的模态框
    const existingModal = document.getElementById('statusUpdateModal');
    if (existingModal) {
        existingModal.remove();
    }
    
    // 添加新的模态框
    document.body.insertAdjacentHTML('beforeend', modalHtml);
    
    // 显示模态框
    const modal = new bootstrap.Modal(document.getElementById('statusUpdateModal'));
    modal.show();
}

function confirmStatusUpdate() {
    const newStatus = document.getElementById('newStatusSelect').value;
    
    if (!newStatus) {
        alert('请选择新的状态');
        return;
    }
    
    const form = document.getElementById('batchActionForm');
    if (!form) {
        alert('表单未找到，请刷新页面重试');
        return;
    }
    
    // 移除之前可能存在的状态输入字段
    const existingStatusInput = form.querySelector('input[name="new_status"]');
    if (existingStatusInput) {
        existingStatusInput.remove();
    }
    
    const statusInput = document.createElement('input');
    statusInput.type = 'hidden';
    statusInput.name = 'new_status';
    statusInput.value = newStatus;
    form.appendChild(statusInput);
    form.action = '{% url "assets:asset_batch_update_status" %}';
    form.submit();
}

function clearSearch() {
    window.location.href = '{% url "assets:asset_list" %}';
}

// 监听单个复选框变化，更新全选状态
document.addEventListener('DOMContentLoaded', function() {
    const assetCheckboxes = document.querySelectorAll('.asset-checkbox');
    const selectAllHeader = document.getElementById('selectAllHeader');
    const root = document.getElementById('assetListRoot');
    const btnComfort = document.getElementById('btnDensityComfort');
    const btnCompact = document.getElementById('btnDensityCompact');
    const selectionToolbar = document.getElementById('selectionToolbar');
    const selectedCountEl = document.getElementById('selectedCount');
    const btnClearSelection = document.getElementById('btnClearSelection');
    const btnBatchRecycle = document.getElementById('btnBatchRecycle');
    const btnBatchDelete = document.getElementById('btnBatchDelete');
    
    assetCheckboxes.forEach(checkbox => {
        checkbox.addEventListener('change', function() {
            const checkedCount = document.querySelectorAll('.asset-checkbox:checked').length;
            const totalCount = assetCheckboxes.length;
            
            if (selectAllHeader) selectAllHeader.checked = checkedCount === totalCount;
            updateSelectionToolbar();
        });
    });

    // 密度偏好初始化
    const savedDensity = localStorage.getItem('assetListDensity');
    if (savedDensity === 'compact') {
        root.classList.remove('asset-density-comfortable');
        root.classList.add('asset-density-compact');
        btnCompact.classList.add('active');
        btnComfort.classList.remove('active');
    }

    function setDensity(mode) {
        if (mode === 'compact') {
            root.classList.remove('asset-density-comfortable');
            root.classList.add('asset-density-compact');
            btnCompact.classList.add('active');
            btnComfort.classList.remove('active');
        } else {
            root.classList.remove('asset-density-compact');
            root.classList.add('asset-density-comfortable');
            btnComfort.classList.add('active');
            btnCompact.classList.remove('active');
        }
        localStorage.setItem('assetListDensity', mode);
    }

    btnComfort.addEventListener('click', () => setDensity('comfortable'));
    btnCompact.addEventListener('click', () => setDensity('compact'));

    // 选择工具条逻辑
    window.updateSelectionToolbar = function() {
        const checked = document.querySelectorAll('.asset-checkbox:checked');
        const count = checked.length;
        selectedCountEl.textContent = count;
        selectionToolbar.style.display = count > 0 ? 'flex' : 'none';
    }
    updateSelectionToolbar();

    btnClearSelection.addEventListener('click', () => {
        document.querySelectorAll('.asset-checkbox:checked').forEach(cb => cb.checked = false);
        if (selectAllHeader) selectAllHeader.checked = false;
        updateSelectionToolbar();
    });

    // 旧的批量回收/删除绑定已移除，改用统一的确认模态 + AJAX（见文件底部 IIFE）

    // 分页跳转：按钮与回车
    const jumpInput = document.getElementById('pageJumpInput');
    const jumpBtn = document.getElementById('pageJumpBtn');
    function goToPage(page) {
        if (!jumpInput) return;
        const maxPage = parseInt(jumpInput?.getAttribute('max') || '1', 10);
        let target = parseInt(page, 10);
        if (isNaN(target)) return;
        if (target < 1) target = 1;
        if (target > maxPage) target = maxPage;
        const params = new URLSearchParams(window.location.search);
        params.set('page', String(target));
        // 保留每页设置
        const perPage = document.getElementById('assetListRoot')?.dataset?.perPage;
        if (perPage) params.set('per_page', perPage);
        window.location.search = params.toString();
    }
    if (jumpBtn) jumpBtn.addEventListener('click', () => goToPage(jumpInput.value));
    if (jumpInput) jumpInput.addEventListener('keyup', (e) => { if (e.key === 'Enter') goToPage(jumpInput.value); });

    // ========== 新增资产 AJAX 模态 ==========
    const btnOpenCreate = document.getElementById('btnOpenCreateAsset');
    const createUrl = '{% url "assets:asset_create" %}';
    const createModalEl = document.getElementById('assetCreateModal');
    const createBodyEl = document.getElementById('assetCreateModalBody');
    const createSubmitBtn = document.getElementById('assetCreateSubmitBtn');

    // 惰性获取/创建 Bootstrap Modal，避免 bootstrap 未加载时报错
    function getCreateModal() {
        if (!createModalEl) return null;
        if (!window.bootstrap || !window.bootstrap.Modal) return null;
        if (!createModalEl._modalInstance) {
            createModalEl._modalInstance = new bootstrap.Modal(createModalEl);
        }
        return createModalEl._modalInstance;
    }

    function getCookie(name) {
        const value = `; ${document.cookie}`;
        const parts = value.split(`; ${name}=`);
        if (parts.length === 2) return parts.pop().split(';').shift();
    }
    function getCsrfToken() {
        return document.querySelector('input[name=csrfmiddlewaretoken]')?.value || getCookie('csrftoken');
    }

    function bindCreateFormSubmit() {
        const form = document.querySelector('#assetCreateModalBody form');
        if (!form) return;
        // 绑定表单提交（拦截）
        form.addEventListener('submit', function (ev) {
            ev.preventDefault();
            submitCreateForm(form);
        });
        // 顶部“保存”按钮触发表单提交
        if (createSubmitBtn) {
            createSubmitBtn.onclick = () => form.requestSubmit();
        }
    }

    async function openCreateModal() {
        const createModal = getCreateModal();
        if (!createModal || !createBodyEl) {
            // Bootstrap 可能尚未就绪，稍后重试一次
            setTimeout(openCreateModal, 50);
            return;
        }
        // 预置加载中
        createBodyEl.innerHTML = '<div class="d-flex align-items-center justify-content-center py-5 text-muted"><div class="text-center"><div class="spinner-border text-primary" role="status" aria-label="加载中"></div><div class="mt-2 small">正在加载表单…</div></div></div>';
        createModal.show();
        try {
            const resp = await fetch(createUrl, {
                headers: { 'X-Requested-With': 'XMLHttpRequest' },
                credentials: 'same-origin'
            });
            const data = await resp.json();
            if (data && data.html) {
                createBodyEl.innerHTML = data.html;
                bindCreateFormSubmit();
            } else {
                createBodyEl.innerHTML = '<div class="text-danger">加载失败</div>';
            }
        } catch (e) {
            createBodyEl.innerHTML = '<div class="text-danger">加载失败，请稍后重试</div>';
        }
    }

    async function submitCreateForm(form) {
        const fd = new FormData(form);
        // 保存按钮禁用并显示小型加载
        let btn = createSubmitBtn || document.querySelector('#assetCreateSubmitBtn');
        let originalHtml = null;
        if (btn) {
            originalHtml = btn.innerHTML;
            btn.disabled = true;
            btn.innerHTML = '<span class="spinner-border spinner-border-sm me-2" role="status" aria-hidden="true"></span>保存中…';
        }
        try {
            const resp = await fetch(createUrl, {
                method: 'POST',
                headers: {
                    'X-Requested-With': 'XMLHttpRequest',
                    'X-CSRFToken': getCsrfToken() || ''
                },
                body: fd,
                credentials: 'same-origin'
            });
            const data = await resp.json();
            if (data.success) {
                if (createModal) createModal.hide();
                showToast(data.message || '资产创建成功');
                await refreshAssetList(data.asset_id);
            } else {
                // 返回错误的表单 HTML
                if (data.html) {
                    createBodyEl.innerHTML = data.html;
                    bindCreateFormSubmit();
                } else {
                    showToast(data.error || '保存失败', 'error');
                }
            }
        } catch (e) {
            showToast('保存失败，请稍后重试', 'error');
        } finally {
            if (btn) {
                btn.disabled = false;
                if (originalHtml !== null) btn.innerHTML = originalHtml;
            }
        }
    }

    async function refreshAssetList(highlightId) {
        try {
            const base = new URL(window.location.href);
            const headerUrl = new URL(base);
            headerUrl.searchParams.set('fragment', 'header');
            const tableUrl = new URL(base);
            tableUrl.searchParams.set('fragment', 'table');
            const pagerUrl = new URL(base);
            pagerUrl.searchParams.set('fragment', 'pagination');

            const headers = { 'X-Requested-With': 'XMLHttpRequest' };
            const opts = { headers, credentials: 'same-origin' };

            const [headerHtml, tableHtml, pagerHtml] = await Promise.all([
                fetch(headerUrl.toString(), opts).then(r => r.text()),
                fetch(tableUrl.toString(), opts).then(r => r.text()),
                fetch(pagerUrl.toString(), opts).then(r => r.text())
            ]);

            let ok = false;
            const headerEl = document.getElementById('assetListHeader');
            if (headerEl && headerHtml) {
                headerEl.innerHTML = headerHtml;
                ok = true;
                // 绑定每页选择器为 AJAX
                bindPerPageAjax();
            }

            const curTbody = document.querySelector('#assetListRoot tbody');
            if (curTbody && tableHtml) {
                curTbody.innerHTML = tableHtml;
                ok = true;
                // 重新绑定行内复选框事件
                const selectAllHeader = document.getElementById('selectAllHeader');
                document.querySelectorAll('.asset-checkbox').forEach(cb => {
                    cb.addEventListener('change', function() {
                        if (!this.checked && selectAllHeader) selectAllHeader.checked = false;
                        const checkedCount = document.querySelectorAll('.asset-checkbox:checked').length;
                        const totalCount = document.querySelectorAll('.asset-checkbox').length;
                        if (selectAllHeader) selectAllHeader.checked = (checkedCount === totalCount);
                        updateSelectionToolbar();
                    });
                });
                updateSelectionToolbar();
                // 高亮新行
                if (highlightId) {
                    const row = document.getElementById(`asset-row-${highlightId}`);
                    if (row) {
                        row.classList.add('row-flash');
                        setTimeout(() => row && row.classList.remove('row-flash'), 2300);
                        row.scrollIntoView({ behavior: 'smooth', block: 'center' });
                    }
                }
            }

            const pagerEl = document.getElementById('assetListPagination');
            if (pagerEl && pagerHtml) {
                pagerEl.innerHTML = pagerHtml;
                ok = true;
                // 绑定跳页按钮
                const jumpBtn = document.getElementById('jumpPageBtn');
                const jumpInput = document.getElementById('jumpPageInput');
                if (jumpBtn && jumpInput) {
                    jumpBtn.addEventListener('click', function() {
                        const target = parseInt(jumpInput.value, 10);
                        if (!target || target < 1) return;
                        const u = new URL(window.location.href);
                        u.searchParams.set('page', String(target));
                        // 无刷新跳页（保持历史）
                        history.pushState({}, '', u.toString());
                        refreshAssetList();
                    });
                }
                // 确保分页与排序链接带上 per_page
                ensurePerPageOnLinks();
            }

            if (!ok) {
                // 回退整页刷新
                window.location.reload();
            }
        } catch (e) {
            window.location.reload();
        }
    }

    // 每页选择器 AJAX 绑定
    function bindPerPageAjax(){
        const sel = document.getElementById('perPageSelect');
        const form = document.getElementById('perPageForm');
        if (!sel) return;
        sel.addEventListener('change', function(ev){
            ev.preventDefault();
            const u = new URL(window.location.href);
            u.searchParams.set('per_page', sel.value);
            u.searchParams.set('page', '1');
            // 更新地址但不刷新
            history.replaceState({}, '', u.toString());
            refreshAssetList();
        }, { once: true }); // 片段刷新后会重新绑定
    }

    // 使用事件委托绑定“新增资产”按钮，避免 header 片段刷新后丢失绑定
    document.addEventListener('click', function(ev){
        const btn = ev.target.closest('#btnOpenCreateAsset');
        if (!btn) return;
        ev.preventDefault();
        openCreateModal();
    }, true);
    
    // ===== 模态框交互：Iframe 打开分配/调拨/维修 =====
    const iframeModalEl = document.getElementById('actionIframeModal');
    const iframeTitleEl = document.getElementById('actionIframeTitle');
    const iframeEl = document.getElementById('actionIframeFrame');
    const iframeLoading = document.getElementById('iframeLoading');
    const iframeError = document.getElementById('iframeError');
    const iframeOpenNewTab = document.getElementById('iframeOpenNewTab');
    const iframeRefreshBtn = document.getElementById('iframeRefreshBtn');
    const iframeSubmitBtn = document.getElementById('iframeSubmitBtn');
    let iframeModal = null;
    if (iframeModalEl) {
        // 安全初始化：仅在 Bootstrap 可用时创建实例，否则延后到 DOMContentLoaded / load
        const initIframeModalInstance = function(){
            try {
                if (!iframeModal && window.bootstrap && window.bootstrap.Modal) {
                    iframeModal = new bootstrap.Modal(iframeModalEl);
                    iframeModalEl.addEventListener('hidden.bs.modal', function(){
                        if (iframeEl) iframeEl.src = 'about:blank';
                        if (iframeLoading) iframeLoading.classList.remove('d-none');
                        if (iframeError) iframeError.classList.add('d-none');
                    });
                }
            } catch (_) {}
        };
        // 立即尝试一次
        initIframeModalInstance();
        // DOM 就绪与窗口加载后再尝试，确保在 Bootstrap 动态加载完成后也能初始化
        document.addEventListener('DOMContentLoaded', initIframeModalInstance);
        window.addEventListener('load', initIframeModalInstance);
    }
    // 处理 iframe 模态框点击事件
    document.body.addEventListener('click', function(e){
        const a = e.target.closest('a[data-modal="iframe"]');
        if (!a) return;
        
        e.preventDefault();
        e.stopPropagation();
        
        const title = a.getAttribute('data-title') || a.textContent?.trim() || '操作';
        if (iframeTitleEl) iframeTitleEl.textContent = title;
        
        // 添加 modal=1 参数，让后端知道这是模态框请求
        let url = a.getAttribute('href');
        try {
            const u = new URL(url, window.location.origin);
            u.searchParams.set('modal', '1');
            url = u.toString();
        } catch (e) {
            // 回退：简单拼接
            url += (url.includes('?') ? '&' : '?') + 'modal=1';
        }
        
        // 设置新窗口打开链接
        if (iframeOpenNewTab) iframeOpenNewTab.href = url;
        
        // 显示加载状态
        if (iframeLoading) iframeLoading.classList.remove('d-none');
        if (iframeError) iframeError.classList.add('d-none');
        
        if (iframeEl) {
            iframeEl.style.visibility = 'hidden';
            iframeEl.src = url;
            
            // 监听 iframe 加载完成
            iframeEl.onload = function() {
                if (iframeLoading) iframeLoading.classList.add('d-none');
                iframeEl.style.visibility = 'visible';
                
                try {
                    // 尝试访问 iframe 内容，如果被同源策略阻止会抛出异常
                    if (iframeEl.contentWindow.location.href === 'about:blank') return;
                } catch (e) {
                    // 如果被同源策略阻止，显示错误
                    if (iframeError) iframeError.classList.remove('d-none');
                    return;
                }
            };
            
            // 监听 iframe 加载错误
            iframeEl.onerror = function() {
                if (iframeLoading) iframeLoading.classList.add('d-none');
                if (iframeError) iframeError.classList.remove('d-none');
            };
            
            // 3秒容错：若仍无法访问文档，显示错误提示
            setTimeout(() => {
                try {
                    // 同源情况下可以访问 contentDocument；若被阻止通常为 null 或抛异常
                    const doc = iframeEl.contentDocument;
                    if (!doc || (doc && doc.body && doc.body.childElementCount === 0)) {
                        if (iframeLoading) iframeLoading.classList.add('d-none');
                        if (iframeError) iframeError.classList.remove('d-none');
                    }
                } catch (ex) {
                    if (iframeLoading) iframeLoading.classList.add('d-none');
                }
            }, 3000);
        }
        
        // 显示模态框
        if (iframeModal) iframeModal.show();
    });
    
    // 监听来自 iframe 成功页的消息，展示 Toast 并仅刷新片段
    window.addEventListener('message', function(e){
        try {
            const data = e?.data || {};
            if (data && data.type === 'asset:operation-success') {
                if (iframeModal) iframeModal.hide();
                showToast(data.message || '操作成功', 'success');
                setTimeout(() => { try { refreshAssetList(); } catch(_) { window.location.reload(); } }, 300);
            }
        } catch (err) { /* no-op */ }
    });

    // 额外：父页面触发表单提交，解决用户未命中 iframe 内提交按钮或拦截导致未发 POST 的情况
    if (iframeSubmitBtn && iframeEl) {
        iframeSubmitBtn.addEventListener('click', function(){
            try {
                const doc = iframeEl.contentDocument;
                if (!doc) { alert('子页面尚未加载，请稍后重试'); return; }
                const form = doc.querySelector('form');
                if (!form) { alert('未找到子页面表单'); return; }
                // 尝试提交
                if (typeof form.requestSubmit === 'function') {
                    form.requestSubmit();
                } else {
                    form.submit();
                }
                // 监听一次 load，检测是否进入成功页，若是则关闭模态并刷新片段
                const onAfterSubmitLoad = () => {
                    try {
                        const d2 = iframeEl.contentDocument;
                        const title = d2?.title || '';
                        const text = (d2?.body?.innerText || '').slice(0, 2000);
                        // 粗略判定是否是我们返回的成功页
                        if (title.includes('成功') || text.includes('更新成功') || text.includes('创建成功')) {
                            if (iframeModal) iframeModal.hide();
                            showToast('操作成功', 'success');
                            setTimeout(() => { try { refreshAssetList(); } catch(_) { window.location.reload(); } }, 300);
                        }
                    } catch (e) { /* no-op */ }
                    iframeEl.removeEventListener('load', onAfterSubmitLoad);
                };
                iframeEl.addEventListener('load', onAfterSubmitLoad);
            } catch (e) {
                alert('触发子页面提交失败：' + (e?.message || e));
            }
        });
    }

    // ===== 确认操作模态框：回收 / 删除（POST） =====
    const confirmModalEl = document.getElementById('confirmActionModal');
    const confirmTitleEl = document.getElementById('confirmActionTitle');
    const confirmMsgEl = document.getElementById('confirmActionMessage');
    const confirmBtn = document.getElementById('confirmActionBtn');
    let confirmModal = null;
    // 提供全局安全获取确认模态实例的方法，避免 bootstrap 尚未加载时报错
    window.getConfirmModalInstance = function(){
        try {
            if (!confirmModalEl) return null;
            if (confirmModal) return confirmModal;
            if (window.bootstrap && window.bootstrap.Modal) {
                confirmModal = bootstrap.Modal.getOrCreateInstance(confirmModalEl);
                return confirmModal;
            }
            return null;
        } catch (_) { return null; }
    }
    function getCsrfToken() {
        // 优先页面中的隐藏输入
        const input = document.querySelector('input[name="csrfmiddlewaretoken"]');
        if (input && input.value) return input.value;
        // 回退从 cookie 获取
        const m = document.cookie.match(/csrftoken=([^;]+)/);
        return m ? decodeURIComponent(m[1]) : '';
    }
    async function postWithCsrf(url) {
        const token = getCsrfToken();
        // 可选第二个参数 body：支持 URLSearchParams 或 FormData
        const body = arguments.length > 1 ? arguments[1] : undefined;
        const isFormData = (typeof FormData !== 'undefined') && body instanceof FormData;
        const headers = { 'X-CSRFToken': token };
        if (body && !isFormData) {
            headers['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8';
        }
        const resp = await fetch(url, {
            method: 'POST',
            headers,
            body,
            credentials: 'same-origin'
        });
        if (!resp.ok) {
            const text = await resp.text();
            throw new Error('请求失败：' + resp.status + '\n' + text);
        }
        return resp;
    }
    document.body.addEventListener('click', function(e){
        const a = e.target.closest('a[data-modal="confirm"]');
        if (!a) return;
        e.preventDefault();
        const title = a.getAttribute('data-title') || '确认操作';
        const message = a.getAttribute('data-message') || '确定执行该操作吗？';
        const postUrl = a.getAttribute('data-post-url');
        if (confirmTitleEl) confirmTitleEl.textContent = title;
        if (confirmMsgEl) confirmMsgEl.textContent = message;
        if (confirmBtn) {
            confirmBtn.setAttribute('data-post-url', postUrl || '');
            confirmBtn.removeAttribute('data-batch');
            confirmBtn.removeAttribute('data-ids');
        }
        const cm = window.getConfirmModalInstance && window.getConfirmModalInstance();
        if (cm) cm.show();
    });
    if (confirmBtn) {
        confirmBtn.addEventListener('click', async function(){
            const url = confirmBtn.getAttribute('data-post-url');
            if (!url) return;
            confirmBtn.disabled = true;
            try {
                // 批量操作：将 data-ids 解析为 asset_ids 参数
                let body = undefined;
                if (confirmBtn.getAttribute('data-batch') === '1') {
                    const idsStr = confirmBtn.getAttribute('data-ids') || '';
                    const params = new URLSearchParams();
                    idsStr.split(',').filter(Boolean).forEach(id => params.append('asset_ids', id));
                    body = params;
                }
                const resp = await postWithCsrf(url, body);
                const cm = window.getConfirmModalInstance && window.getConfirmModalInstance();
                if (cm) cm.hide();
                showToast('操作成功', 'success');
                setTimeout(() => { try { refreshAssetList(); } catch(_) { window.location.reload(); } }, 300);
            } catch (err) {
                const msg = (err && err.message) ? err.message : '请求失败，请稍后再试';
                showToast(msg, 'error');
            } finally {
                confirmBtn.disabled = false;
            }
        });
    }

    // 统一为分页与排序链接追加 per_page 参数
    function ensurePerPageOnLinks(){
        const perSel = document.getElementById('perPageSelect');
        const perVal = perSel && perSel.value ? perSel.value : (document.getElementById('assetListRoot')?.dataset.perPage || '');
        if (!perVal) return;
        // 分页链接
        document.querySelectorAll('nav .pagination a.page-link').forEach(a => {
            try {
                const u = new URL(a.getAttribute('href'), window.location.origin);
                if (!u.searchParams.get('per_page')) u.searchParams.set('per_page', perVal);
                a.setAttribute('href', u.pathname + '?' + u.searchParams.toString());
            } catch (e) {
                // 相对链接回退
                const href = a.getAttribute('href') || '';
                if (!href) return;
                if (href.includes('per_page=')) return;
                a.setAttribute('href', href + (href.includes('?') ? '&' : '?') + 'per_page=' + encodeURIComponent(perVal));
            }
        });
        // 表头排序链接
        document.querySelectorAll('thead a.text-white.text-decoration-none').forEach(a => {
            try {
                const u = new URL(a.getAttribute('href'), window.location.origin);
                if (!u.searchParams.get('per_page')) u.searchParams.set('per_page', perVal);
                a.setAttribute('href', u.pathname + '?' + u.searchParams.toString());
            } catch (e) {
                const href = a.getAttribute('href') || '';
                if (!href) return;
                if (href.includes('per_page=')) return;
                a.setAttribute('href', href + (href.includes('?') ? '&' : '?') + 'per_page=' + encodeURIComponent(perVal));
            }
        });
    }

    // 初次绑定
    bindPerPageAjax();
    ensurePerPageOnLinks();
});

// ========== 通用资产操作（编辑/分配/调拨/维修）AJAX 模态 ==========
const actionModalEl = document.getElementById('assetActionAjaxModal');
const actionBodyEl = document.getElementById('assetActionAjaxBody');
const actionTitleEl = document.getElementById('assetActionAjaxTitle');
const actionSubmitBtn = document.getElementById('assetActionAjaxSubmitBtn');
let currentActionUrl = null;

function getActionModal() {
  if (!actionModalEl) return null;
  return bootstrap.Modal.getOrCreateInstance(actionModalEl);
}

function getCsrfTokenFrom(bodyRoot){
  try { return bodyRoot.querySelector('input[name="csrfmiddlewaretoken"]').value; } catch(_) {}
  // 退化：尝试从 Cookie
  const m = document.cookie.match(/csrftoken=([^;]+)/);
  return m ? decodeURIComponent(m[1]) : '';
}

async function openActionAjaxModal(url, title) {
  const modal = getActionModal();
  if (!modal || !actionBodyEl) return;
  if (actionTitleEl) actionTitleEl.textContent = title || '操作';
  actionBodyEl.innerHTML = '<div class="d-flex align-items-center justify-content-center py-5 text-muted"><div class="text-center"><div class="spinner-border text-primary" role="status" aria-label="加载中"></div><div class="mt-2 small">正在加载表单…</div></div></div>';
  currentActionUrl = url;
  modal.show();
  try {
    const resp = await fetch(url, { headers: { 'X-Requested-With': 'XMLHttpRequest' }, credentials: 'same-origin' });
    const data = await resp.json();
    if (data && data.html) {
      actionBodyEl.innerHTML = data.html;
    } else {
      actionBodyEl.innerHTML = '<div class="text-danger">加载失败</div>';
    }
  } catch (e) {
    actionBodyEl.innerHTML = '<div class="text-danger">加载失败，请稍后重试</div>';
  }
}

async function submitActionAjaxForm() {
  if (!currentActionUrl || !actionBodyEl) return;
  const form = actionBodyEl.querySelector('form');
  if (!form) { showToast('未找到表单', 'error'); return; }
  const formData = new FormData(form);
  const csrf = getCsrfTokenFrom(form) || '';
  actionSubmitBtn && (actionSubmitBtn.disabled = true);
  try {
    const resp = await fetch(currentActionUrl, {
      method: 'POST',
      headers: {
        'X-Requested-With': 'XMLHttpRequest',
        ...(csrf ? { 'X-CSRFToken': csrf } : {})
      },
      body: formData,
      credentials: 'same-origin'
    });
    const data = await resp.json();
    if (resp.ok && data && (data.success || data.asset_id)) {
      // 成功
      const modal = getActionModal();
      if (modal) modal.hide();
      showToast(data.message || '操作成功', 'success');
      setTimeout(() => { try { refreshAssetList(); } catch(_) { window.location.reload(); } }, 200);
    } else {
      // 校验错误：返回部分 HTML
      if (data && data.html) {
        actionBodyEl.innerHTML = data.html;
      } else {
        showToast((data && data.message) || '提交失败', 'error');
      }
    }
  } catch (e) {
    showToast('网络错误，请稍后重试', 'error');
  } finally {
    actionSubmitBtn && (actionSubmitBtn.disabled = false);
  }
}

// 事件绑定：打开通用 AJAX 模态
document.body.addEventListener('click', function(e){
  const a = e.target.closest('a[data-modal="ajax"]');
  if (!a) return;
  e.preventDefault();
  const href = a.getAttribute('href');
  if (!href) return;
  const title = a.getAttribute('data-title') || a.textContent?.trim() || '操作';
  openActionAjaxModal(href, title);
});

// 事件绑定：提交通用 AJAX 模态内表单
if (actionSubmitBtn) {
  actionSubmitBtn.addEventListener('click', submitActionAjaxForm);
}

// ========== 批量操作：回收 / 删除 使用确认模态 + AJAX ==========
(function(){
  const btnBatchRecycle = document.getElementById('btnBatchRecycle');
  const btnBatchDelete = document.getElementById('btnBatchDelete');
  const btnMenuBatchDelete = document.getElementById('btnMenuBatchDelete');

  // 本地初始化确认模态相关元素，避免作用域问题
  const confirmModalEl = document.getElementById('confirmActionModal');
  const confirmTitleEl = document.getElementById('confirmActionTitle');
  const confirmMsgEl = document.getElementById('confirmActionMessage');
  const confirmBtn = document.getElementById('confirmActionBtn');
  const confirmModal = (function(){
    if (!confirmModalEl || !window.bootstrap || !window.bootstrap.Modal) return null;
    return bootstrap.Modal.getOrCreateInstance(confirmModalEl);
  })();

  function getSelectedAssetIds(){
    return Array.from(document.querySelectorAll('.asset-checkbox:checked')).map(cb => cb.value);
  }
  function openBatchConfirm(ids, type){
    if (!ids.length) { showToast('请选择要操作的资产', 'error'); return; }
    const title = type === 'recycle' ? '批量回收资产' : '批量删除资产';
    const message = type === 'recycle'
      ? `确定要回收选中的 ${ids.length} 个资产吗？回收后将清空使用人并设置为闲置。`
      : `确定要删除选中的 ${ids.length} 个资产吗？此操作不可撤销！`;
    const postUrl = type === 'recycle'
      ? '{% url "assets:asset_batch_recycle" %}'
      : '{% url "assets:asset_batch_delete" %}';
    if (confirmTitleEl) confirmTitleEl.textContent = title;
    if (confirmMsgEl) confirmMsgEl.textContent = message;
    if (confirmBtn) {
      confirmBtn.setAttribute('data-post-url', postUrl);
      confirmBtn.setAttribute('data-batch', '1');
      confirmBtn.setAttribute('data-ids', ids.join(','));
    }
    // 使用全局安全获取器，避免 Bootstrap 尚未就绪时获取失败
    const cm = (window.getConfirmModalInstance && window.getConfirmModalInstance()) || confirmModal;
    if (cm) cm.show();
  }

  function handleBatch(type){
    const ids = getSelectedAssetIds();
    openBatchConfirm(ids, type);
  }

  btnBatchRecycle && btnBatchRecycle.addEventListener('click', () => handleBatch('recycle'));
  btnBatchDelete && btnBatchDelete.addEventListener('click', () => handleBatch('delete'));
  btnMenuBatchDelete && btnMenuBatchDelete.addEventListener('click', (e) => { e.preventDefault(); handleBatch('delete'); });
})();

</script>
{% endblock %}